import multiprocessing


def _process_tasks(pipe_in):
    from tqdm import tqdm
    tasks = {}
    while True:
        cmds = pipe_in.recv()
        which, name = cmds.pop('cmd'), cmds.pop('name')

        # 关闭所有
        if which is None:
            for _, v in tasks.items():
                v.close()
            return

        if which == "u":
            task = tasks.get(name)
            if task:
                task.update(cmds['n'])
        elif which == "n":
            if name in tasks:
                continue
            tasks[name] = tqdm(desc=name, **cmds)
        elif which == "c":
            task = tasks.get(name)
            if task:
                task.close()


class TaskMan(object):
    def __init__(self, key):
        self._pipe_out = key

    def new_task(self, name: str, total: int = 100, useBytes: bool = False):
        if useBytes:
            self._send("n",
                       name,
                       total=total,
                       unit='B',
                       unit_scale=True,
                       unit_divisor=1024)
        else:
            self._send("n", name, total=total, unit='it')

    def update_task(self, name: str, n: int):
        self._send('u', name, n=n)

    def close_task(self, name: str):
        self._send('c', name)

    def _send(self, cmd: str, name: str, **kwargs):
        args = {'cmd': cmd, 'name': name}
        args.update(kwargs)
        self._pipe_out.send(args)


class DownloaderUI(object):
    def __init__(self):
        self._pipe_in, self._pipe_out = multiprocessing.Pipe(False)
        self._p = multiprocessing.Process(target=_process_tasks,
                                          args=(self._pipe_in, ))
        self._p.start()

    def join(self):
        args = {'cmd': None, 'name': None}
        self._pipe_out.send(args)
        self._p.join()

    @property
    def key(self):
        return self._pipe_out
